# coding: utf-8


import numpy as np
import pandas as pd


def np_ndarray():
    """
class ndarray(builtins.object)
 |  ndarray(shape, dtype=float, buffer=None, offset=0,
 |          strides=None, order=None)
 |
 |  An array object represents a multidimensional, homogeneous array
 |  of fixed-size items.  An associated data-type object describes the
 |  format of each element in the array (its byte-order, how many bytes it
 |  occupies in memory, whether it is an integer, a floating point number,
 |  or something else, etc.)
 |
 |  Arrays should be constructed using `array`, `zeros` or `empty` (refer
 |  to the See Also section below).  The parameters given here refer to
 |  a low-level method (`ndarray(...)`) for instantiating an array.
 |
 |  For more information, refer to the `numpy` module and examine the
 |  methods and attributes of an array.
 |
 |  Parameters
 |  ----------
 |  (for the __new__ method; see Notes below)
 |
 |  shape : tuple of ints
 |      Shape of created array.
 |  dtype : data-type, optional
 |      Any object that can be interpreted as a numpy data type.
 |  buffer : object exposing buffer interface, optional
 |      Used to fill the array with data.
 |  offset : int, optional
 |      Offset of array data in buffer.
 |  strides : tuple of ints, optional
 |      Strides of data in memory.
 |  order : {'C', 'F'}, optional
 |      Row-major (C-style) or column-major (Fortran-style) order.
 |
 |  Attributes
 |  ----------
 |  T : ndarray
 |      Transpose of the array.
 |  data : buffer
 |      The array's elements, in memory.
 |  dtype : dtype object
 |      Describes the format of the elements in the array.
 |  flags : dict
 |      Dictionary containing information related to memory use, e.g.,
 |      'C_CONTIGUOUS', 'OWNDATA', 'WRITEABLE', etc.
 |  flat : numpy.flatiter object
 |      Flattened version of the array as an iterator.  The iterator
 |      allows assignments, e.g., ``x.flat = 3`` (See `ndarray.flat` for
 |      assignment examples; TODO).
 |  imag : ndarray
 |      Imaginary part of the array.
 |  real : ndarray
 |      Real part of the array.
 |  size : int
 |      Number of elements in the array.
 |  itemsize : int
 |      The memory use of each array element in bytes.
 |  nbytes : int
 |      The total number of bytes required to store the array data,
 |      i.e., ``itemsize * size``.
 |  ndim : int
 |      The array's number of dimensions.
 |  shape : tuple of ints
 |      Shape of the array.
 |  strides : tuple of ints
 |      The step-size required to move from one element to the next in
 |      memory. For example, a contiguous ``(3, 4)`` array of type
 |      ``int16`` in C-order has strides ``(8, 2)``.  This implies that
 |      to move from element to element in memory requires jumps of 2 bytes.
 |      To move from row-to-row, one needs to jump 8 bytes at a time
 |      (``2 * 4``).
 |  ctypes : ctypes object
 |      Class containing properties of the array needed for interaction
 |      with ctypes.
 |  base : ndarray
 |      If the array is a view into another array, that array is its `base`
 |      (unless that array is also a view).  The `base` array is where the
 |      array data is actually stored.
 |
 |  See Also
 |  --------
 |  array : Construct an array.
 |  zeros : Create an array, each element of which is zero.
 |  empty : Create an array, but leave its allocated memory unchanged (i.e.,
 |          it contains "garbage").
 |  dtype : Create a data-type.
 |
 |  Notes
 |  -----
 |  There are two modes of creating an array using ``__new__``:
 |
 |  1. If `buffer` is None, then only `shape`, `dtype`, and `order`
 |     are used.
 |  2. If `buffer` is an object exposing the buffer interface, then
 |     all keywords are interpreted.
 |
 |  No ``__init__`` method is needed because the array is fully initialized
 |  after the ``__new__`` method.
 |
 |  Examples
 |  --------
 |  These examples illustrate the low-level `ndarray` constructor.  Refer
 |  to the `See Also` section above for easier ways of constructing an
 |  ndarray.
 |
 |  First mode, `buffer` is None:
 |
 |  >>> np.ndarray(shape=(2,2), dtype=float, order='F')
 |  array([[ -1.13698227e+002,   4.25087011e-303],
 |         [  2.88528414e-306,   3.27025015e-309]])         #random
 |
 |  Second mode:
 |
 |  >>> np.ndarray((2,), buffer=np.array([1,2,3]),
 |  ...            offset=np.int_().itemsize,
 |  ...            dtype=int) # offset = 1*itemsize, i.e. skip first element
 |  array([2, 3])
 |
 |  Methods defined here:
 |
 |  __abs__(self, /)
 |      abs(self)
 |
 |  __add__(self, value, /)
 |      Return self+value.
 |
 |  __and__(self, value, /)
 |      Return self&value.
 |
 |  __array__(...)
 |      a.__array__(|dtype) -> reference if type unchanged, copy otherwise.
 |
 |      Returns either a new reference to self if dtype is not given or a new array
 |      of provided data type if dtype is different from the current dtype of the
 |      array.
 |
 |  __array_prepare__(...)
 |      a.__array_prepare__(obj) -> Object of same type as ndarray object obj.
 |
 |  __array_ufunc__(...)
 |
 |  __array_wrap__(...)
 |      a.__array_wrap__(obj) -> Object of same type as ndarray object a.
 |
 |  __bool__(self, /)
 |      self != 0
 |
 |  __complex__(...)
 |
 |  __contains__(self, key, /)
 |      Return key in self.
 |
 |  __copy__(...)
 |      a.__copy__()
 |
 |      Used if :func:`copy.copy` is called on an array. Returns a copy of the array.
 |
 |      Equivalent to ``a.copy(order='K')``.
 |
 |  __deepcopy__(...)
 |      a.__deepcopy__(memo, /) -> Deep copy of array.
 |
 |      Used if :func:`copy.deepcopy` is called on an array.
 |
 |  __delitem__(self, key, /)
 |      Delete self[key].
 |
 |  __divmod__(self, value, /)
 |      Return divmod(self, value).
 |
 |  __eq__(self, value, /)
 |      Return self==value.
 |
 |  __float__(self, /)
 |      float(self)
 |
 |  __floordiv__(self, value, /)
 |      Return self//value.
 |
 |  __format__(...)
 |      Default object formatter.
 |
 |  __ge__(self, value, /)
 |      Return self>=value.
 |
 |  __getitem__(self, key, /)
 |      Return self[key].
 |
 |  __gt__(self, value, /)
 |      Return self>value.
 |
 |  __iadd__(self, value, /)
 |      Return self+=value.
 |
 |  __iand__(self, value, /)
 |      Return self&=value.
 |
 |  __ifloordiv__(self, value, /)
 |      Return self//=value.
 |
 |  __ilshift__(self, value, /)
 |      Return self<<=value.
 |
 |  __imatmul__(self, value, /)
 |      Return self@=value.
 |
 |  __imod__(self, value, /)
 |      Return self%=value.
 |
 |  __imul__(self, value, /)
 |      Return self*=value.
 |
 |  __index__(self, /)
 |      Return self converted to an integer, if self is suitable for use as an index into a list.
 |
 |  __int__(self, /)
 |      int(self)
 |
 |  __invert__(self, /)
 |      ~self
 |
 |  __ior__(self, value, /)
    ......
 |  all(...)
 |      a.all(axis=None, out=None, keepdims=False)
 |
 |      Returns True if all elements evaluate to True.
 |
 |      Refer to `numpy.all` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.all : equivalent function
 |
 |  any(...)
 |      a.any(axis=None, out=None, keepdims=False)
 |
 |      Returns True if any of the elements of `a` evaluate to True.
 |
 |      Refer to `numpy.any` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.any : equivalent function
 |
 |  argmax(...)
 |      a.argmax(axis=None, out=None)
 |
 |      Return indices of the maximum values along the given axis.
 |
 |      Refer to `numpy.argmax` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.argmax : equivalent function
 |
 |  argmin(...)
 |      a.argmin(axis=None, out=None)
 |
 |      Return indices of the minimum values along the given axis of `a`.
 |
 |      Refer to `numpy.argmin` for detailed documentation.
 |
 |      See Also
 |      --------
 |      numpy.argmin : equivalent function
 |
 |  argpartition(...)
 |      a.argpartition(kth, axis=-1, kind='introselect', order=None)
 |
 |      Returns the indices that would partition this array.
 |
 |      Refer to `numpy.argpartition` for full documentation.
 |
 |      .. versionadded:: 1.8.0
 |
 |      See Also
 |      --------
 |      numpy.argpartition : equivalent function
 |
 |  argsort(...)
 |      a.argsort(axis=-1, kind='quicksort', order=None)
 |
 |      Returns the indices that would sort this array.
 |
 |      Refer to `numpy.argsort` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.argsort : equivalent function
 |
 |  astype(...)
 |      a.astype(dtype, order='K', casting='unsafe', subok=True, copy=True)
 |
 |      Copy of the array, cast to a specified type.
 |
 |      Parameters
 |      ----------
 |      dtype : str or dtype
 |          Typecode or data-type to which the array is cast.
 |      order : {'C', 'F', 'A', 'K'}, optional
 |          Controls the memory layout order of the result.
 |          'C' means C order, 'F' means Fortran order, 'A'
 |          means 'F' order if all the arrays are Fortran contiguous,
 |          'C' order otherwise, and 'K' means as close to the
 |          order the array elements appear in memory as possible.
 |          Default is 'K'.
 |      casting : {'no', 'equiv', 'safe', 'same_kind', 'unsafe'}, optional
 |          Controls what kind of data casting may occur. Defaults to 'unsafe'
 |          for backwards compatibility.
 |
 |            * 'no' means the data types should not be cast at all.
 |            * 'equiv' means only byte-order changes are allowed.
 |            * 'safe' means only casts which can preserve values are allowed.
 |            * 'same_kind' means only safe casts or casts within a kind,
 |              like float64 to float32, are allowed.
 |            * 'unsafe' means any data conversions may be done.
 |      subok : bool, optional
 |          If True, then sub-classes will be passed-through (default), otherwise
 |          the returned array will be forced to be a base-class array.
 |      copy : bool, optional
 |          By default, astype always returns a newly allocated array. If this
 |          is set to false, and the `dtype`, `order`, and `subok`
 |          requirements are satisfied, the input array is returned instead
 |          of a copy.
 |
 |      Returns
 |      -------
 |      arr_t : ndarray
 |          Unless `copy` is False and the other conditions for returning the input
 |          array are satisfied (see description for `copy` input parameter), `arr_t`
 |          is a new array of the same shape as the input array, with dtype, order
 |          given by `dtype`, `order`.
 |
 |      Notes
 |      -----
 |      Starting in NumPy 1.9, astype method now returns an error if the string
 |      dtype to cast to is not long enough in 'safe' casting mode to hold the max
 |      value of integer/float array that is being casted. Previously the casting
 |      was allowed even if the result was truncated.
 |
 |      Raises
 |      ------
 |      ComplexWarning
 |          When casting from complex to float or int. To avoid this,
 |          one should use ``a.real.astype(t)``.
 |
 |      Examples
 |      --------
 |      >>> x = np.array([1, 2, 2.5])
 |      >>> x
 |      array([ 1. ,  2. ,  2.5])
 |
 |      >>> x.astype(int)
 |      array([1, 2, 2])
 |
 |  byteswap(...)
 |      a.byteswap(inplace=False)
 |
 |      Swap the bytes of the array elements
 |
 |      Toggle between low-endian and big-endian data representation by
 |      returning a byteswapped array, optionally swapped in-place.
 |
 |      Parameters
 |      ----------
 |      inplace : bool, optional
 |          If ``True``, swap bytes in-place, default is ``False``.
 |
 |      Returns
 |      -------
 |      out : ndarray
 |          The byteswapped array. If `inplace` is ``True``, this is
 |          a view to self.
 |
 |      Examples
 |      --------
 |      >>> A = np.array([1, 256, 8755], dtype=np.int16)
 |      >>> map(hex, A)
 |      ['0x1', '0x100', '0x2233']
 |      >>> A.byteswap(inplace=True)
 |      array([  256,     1, 13090], dtype=int16)
 |      >>> map(hex, A)
 |      ['0x100', '0x1', '0x3322']
 |
 |      Arrays of strings are not swapped
 |
 |      >>> A = np.array(['ceg', 'fac'])
 |      >>> A.byteswap()
 |      array(['ceg', 'fac'],
 |            dtype='|S3')
 |
 |  choose(...)
 |      a.choose(choices, out=None, mode='raise')
 |
 |      Use an index array to construct a new array from a set of choices.
 |
 |      Refer to `numpy.choose` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.choose : equivalent function
 |
 |  clip(...)
 |      a.clip(min=None, max=None, out=None)
 |
 |      Return an array whose values are limited to ``[min, max]``.
 |      One of max or min must be given.
 |
 |      Refer to `numpy.clip` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.clip : equivalent function
 |
 |  compress(...)
 |      a.compress(condition, axis=None, out=None)
 |
 |      Return selected slices of this array along given axis.
 |
 |      Refer to `numpy.compress` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.compress : equivalent function
 |
 |  conj(...)
 |      a.conj()
 |
 |      Complex-conjugate all elements.
 |
 |      Refer to `numpy.conjugate` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.conjugate : equivalent function
 |
 |  conjugate(...)
 |      a.conjugate()
 |
 |      Return the complex conjugate, element-wise.
 |
 |      Refer to `numpy.conjugate` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.conjugate : equivalent function
 |
 |  copy(...)
 |      a.copy(order='C')
 |
 |      Return a copy of the array.
 |
 |      Parameters
 |      ----------
 |      order : {'C', 'F', 'A', 'K'}, optional
 |          Controls the memory layout of the copy. 'C' means C-order,
 |          'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous,
 |          'C' otherwise. 'K' means match the layout of `a` as closely
 |          as possible. (Note that this function and :func:`numpy.copy` are very
 |          similar, but have different default values for their order=
 |          arguments.)
 |
 |      See also
 |      --------
 |      numpy.copy
 |      numpy.copyto
 |
 |      Examples
 |      --------
 |      >>> x = np.array([[1,2,3],[4,5,6]], order='F')
 |
 |      >>> y = x.copy()
 |
 |      >>> x.fill(0)
 |
 |      >>> x
 |      array([[0, 0, 0],
 |             [0, 0, 0]])
 |
 |      >>> y
 |      array([[1, 2, 3],
 |             [4, 5, 6]])
 |
 |      >>> y.flags['C_CONTIGUOUS']
 |      True
 |
 |  cumprod(...)
 |      a.cumprod(axis=None, dtype=None, out=None)
 |
 |      Return the cumulative product of the elements along the given axis.
 |
 |      Refer to `numpy.cumprod` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.cumprod : equivalent function
 |
 |  cumsum(...)
 |      a.cumsum(axis=None, dtype=None, out=None)
 |
 |      Return the cumulative sum of the elements along the given axis.
 |
 |      Refer to `numpy.cumsum` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.cumsum : equivalent function
 |
 |  diagonal(...)
 |      a.diagonal(offset=0, axis1=0, axis2=1)
 |
 |      Return specified diagonals. In NumPy 1.9 the returned array is a
 |      read-only view instead of a copy as in previous NumPy versions.  In
 |      a future version the read-only restriction will be removed.
 |
 |      Refer to :func:`numpy.diagonal` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.diagonal : equivalent function
 |
 |  dot(...)
 |      a.dot(b, out=None)
 |
 |      Dot product of two arrays.
 |
 |      Refer to `numpy.dot` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.dot : equivalent function
 |
 |      Examples
 |      --------
 |      >>> a = np.eye(2)
 |      >>> b = np.ones((2, 2)) * 2
 |      >>> a.dot(b)
 |      array([[ 2.,  2.],
 |             [ 2.,  2.]])
 |
 |      This array method can be conveniently chained:
 |
 |      >>> a.dot(b).dot(b)
 |      array([[ 8.,  8.],
 |             [ 8.,  8.]])
 |
 |  dump(...)
 |      a.dump(file)
 |
 |      Dump a pickle of the array to the specified file.
 |      The array can be read back with pickle.load or numpy.load.
 |
 |      Parameters
 |      ----------
 |      file : str
 |          A string naming the dump file.
 |
 |  dumps(...)
 |      a.dumps()
 |
 |      Returns the pickle of the array as a string.
 |      pickle.loads or numpy.loads will convert the string back to an array.
 |
 |      Parameters
 |      ----------
 |      None
 |
 |  fill(...)
 |      a.fill(value)
 |
 |      Fill the array with a scalar value.
 |
 |      Parameters
 |      ----------
 |      value : scalar
 |          All elements of `a` will be assigned this value.
 |
 |      Examples
 |      --------
 |      >>> a = np.array([1, 2])
 |      >>> a.fill(0)
 |      >>> a
 |      array([0, 0])
 |      >>> a = np.empty(2)
 |      >>> a.fill(1)
 |      >>> a
 |      array([ 1.,  1.])
 |
 |  flatten(...)
 |      a.flatten(order='C')
 |
 |      Return a copy of the array collapsed into one dimension.
 |
 |      Parameters
 |      ----------
 |      order : {'C', 'F', 'A', 'K'}, optional
 |          'C' means to flatten in row-major (C-style) order.
 |          'F' means to flatten in column-major (Fortran-
 |          style) order. 'A' means to flatten in column-major
 |          order if `a` is Fortran *contiguous* in memory,
 |          row-major order otherwise. 'K' means to flatten
 |          `a` in the order the elements occur in memory.
 |          The default is 'C'.
 |
 |      Returns
 |      -------
 |      y : ndarray
 |          A copy of the input array, flattened to one dimension.
 |
 |      See Also
 |      --------
 |      ravel : Return a flattened array.
 |      flat : A 1-D flat iterator over the array.
 |
 |      Examples
 |      --------
 |      >>> a = np.array([[1,2], [3,4]])
 |      >>> a.flatten()
 |      array([1, 2, 3, 4])
 |      >>> a.flatten('F')
 |      array([1, 3, 2, 4])
 |
 |  getfield(...)
 |      a.getfield(dtype, offset=0)
 |
 |      Returns a field of the given array as a certain type.
 |
 |      A field is a view of the array data with a given data-type. The values in
 |      the view are determined by the given type and the offset into the current
 |      array in bytes. The offset needs to be such that the view dtype fits in the
 |      array dtype; for example an array of dtype complex128 has 16-byte elements.
 |      If taking a view with a 32-bit integer (4 bytes), the offset needs to be
 |      between 0 and 12 bytes.
 |
 |      Parameters
 |      ----------
 |      dtype : str or dtype
 |          The data type of the view. The dtype size of the view can not be larger
 |          than that of the array itself.
 |      offset : int
 |          Number of bytes to skip before beginning the element view.
 |
 |      Examples
 |      --------
 |      >>> x = np.diag([1.+1.j]*2)
 |      >>> x[1, 1] = 2 + 4.j
 |      >>> x
 |      array([[ 1.+1.j,  0.+0.j],
 |             [ 0.+0.j,  2.+4.j]])
 |      >>> x.getfield(np.float64)
 |      array([[ 1.,  0.],
 |             [ 0.,  2.]])
 |
 |      By choosing an offset of 8 bytes we can select the complex part of the
 |      array for our view:
 |
 |      >>> x.getfield(np.float64, offset=8)
 |      array([[ 1.,  0.],
 |         [ 0.,  4.]])
 |
 |  item(...)
 |      a.item(*args)
 |
 |      Copy an element of an array to a standard Python scalar and return it.
 |
 |      Parameters
 |      ----------
 |      \*args : Arguments (variable number and type)
 |
 |          * none: in this case, the method only works for arrays
 |            with one element (`a.size == 1`), which element is
 |            copied into a standard Python scalar object and returned.
 |
 |          * int_type: this argument is interpreted as a flat index into
 |            the array, specifying which element to copy and return.
 |
 |          * tuple of int_types: functions as does a single int_type argument,
 |            except that the argument is interpreted as an nd-index into the
 |            array.
 |
 |      Returns
 |      -------
 |      z : Standard Python scalar object
 |          A copy of the specified element of the array as a suitable
 |          Python scalar
 |
 |      Notes
 |      -----
 |      When the data type of `a` is longdouble or clongdouble, item() returns
 |      a scalar array object because there is no available Python scalar that
 |      would not lose information. Void arrays return a buffer object for item(),
 |      unless fields are defined, in which case a tuple is returned.
 |
 |      `item` is very similar to a[args], except, instead of an array scalar,
 |      a standard Python scalar is returned. This can be useful for speeding up
 |      access to elements of the array and doing arithmetic on elements of the
 |      array using Python's optimized math.
 |
 |      Examples
 |      --------
 |      >>> x = np.random.randint(9, size=(3, 3))
 |      >>> x
 |      array([[3, 1, 7],
 |             [2, 8, 3],
 |             [8, 5, 3]])
 |      >>> x.item(3)
 |      2
 |      >>> x.item(7)
 |      5
 |      >>> x.item((0, 1))
 |      1
 |      >>> x.item((2, 2))
 |      3
 |
 |  itemset(...)
 |      a.itemset(*args)
 |
 |      Insert scalar into an array (scalar is cast to array's dtype, if possible)
 |
 |      There must be at least 1 argument, and define the last argument
 |      as *item*.  Then, ``a.itemset(*args)`` is equivalent to but faster
 |      than ``a[args] = item``.  The item should be a scalar value and `args`
 |      must select a single item in the array `a`.
 |
 |      Parameters
 |      ----------
 |      \*args : Arguments
 |          If one argument: a scalar, only used in case `a` is of size 1.
 |          If two arguments: the last argument is the value to be set
 |          and must be a scalar, the first argument specifies a single array
 |          element location. It is either an int or a tuple.
 |
 |      Notes
 |      -----
 |      Compared to indexing syntax, `itemset` provides some speed increase
 |      for placing a scalar into a particular location in an `ndarray`,
 |      if you must do this.  However, generally this is discouraged:
 |      among other problems, it complicates the appearance of the code.
 |      Also, when using `itemset` (and `item`) inside a loop, be sure
 |      to assign the methods to a local variable to avoid the attribute
 |      look-up at each loop iteration.
 |
 |      Examples
 |      --------
 |      >>> x = np.random.randint(9, size=(3, 3))
 |      >>> x
 |      array([[3, 1, 7],
 |             [2, 8, 3],
 |             [8, 5, 3]])
 |      >>> x.itemset(4, 0)
 |      >>> x.itemset((2, 2), 9)
 |      >>> x
 |      array([[3, 1, 7],
 |             [2, 0, 3],
 |             [8, 5, 9]])
 |
 |  max(...)
 |      a.max(axis=None, out=None, keepdims=False)
 |
 |      Return the maximum along a given axis.
 |
 |      Refer to `numpy.amax` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.amax : equivalent function
 |
 |  mean(...)
 |      a.mean(axis=None, dtype=None, out=None, keepdims=False)
 |
 |      Returns the average of the array elements along given axis.
 |
 |      Refer to `numpy.mean` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.mean : equivalent function
 |
 |  min(...)
 |      a.min(axis=None, out=None, keepdims=False)
 |
 |      Return the minimum along a given axis.
 |
 |      Refer to `numpy.amin` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.amin : equivalent function
 |
 |  newbyteorder(...)
 |      arr.newbyteorder(new_order='S')
 |
 |      Return the array with the same data viewed with a different byte order.
 |
 |      Equivalent to::
 |
 |          arr.view(arr.dtype.newbytorder(new_order))
 |
 |      Changes are also made in all fields and sub-arrays of the array data
 |      type.
 |
 |
 |
 |      Parameters
 |      ----------
 |      new_order : string, optional
 |          Byte order to force; a value from the byte order specifications
 |          below. `new_order` codes can be any of:
 |
 |          * 'S' - swap dtype from current to opposite endian
 |          * {'<', 'L'} - little endian
 |          * {'>', 'B'} - big endian
 |          * {'=', 'N'} - native order
 |          * {'|', 'I'} - ignore (no change to byte order)
 |
 |          The default value ('S') results in swapping the current
 |          byte order. The code does a case-insensitive check on the first
 |          letter of `new_order` for the alternatives above.  For example,
 |          any of 'B' or 'b' or 'biggish' are valid to specify big-endian.
 |
 |
 |      Returns
 |      -------
 |      new_arr : array
 |          New array object with the dtype reflecting given change to the
 |          byte order.
 |
 |  nonzero(...)
 |      a.nonzero()
 |
 |      Return the indices of the elements that are non-zero.
 |
 |      Refer to `numpy.nonzero` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.nonzero : equivalent function
 |
 |  partition(...)
 |      a.partition(kth, axis=-1, kind='introselect', order=None)
 |
 |      Rearranges the elements in the array in such a way that the value of the
 |      element in kth position is in the position it would be in a sorted array.
 |      All elements smaller than the kth element are moved before this element and
 |      all equal or greater are moved behind it. The ordering of the elements in
 |      the two partitions is undefined.
 |
 |      .. versionadded:: 1.8.0
 |
 |      Parameters
 |      ----------
 |      kth : int or sequence of ints
 |          Element index to partition by. The kth element value will be in its
 |          final sorted position and all smaller elements will be moved before it
 |          and all equal or greater elements behind it.
 |          The order of all elements in the partitions is undefined.
 |          If provided with a sequence of kth it will partition all elements
 |          indexed by kth of them into their sorted position at once.
 |      axis : int, optional
 |          Axis along which to sort. Default is -1, which means sort along the
 |          last axis.
 |      kind : {'introselect'}, optional
 |          Selection algorithm. Default is 'introselect'.
 |      order : str or list of str, optional
 |          When `a` is an array with fields defined, this argument specifies
 |          which fields to compare first, second, etc. A single field can
 |          be specified as a string, and not all fields need to be specified,
 |          but unspecified fields will still be used, in the order in which
 |          they come up in the dtype, to break ties.
 |
 |      See Also
 |      --------
 |      numpy.partition : Return a parititioned copy of an array.
 |      argpartition : Indirect partition.
 |      sort : Full sort.
 |
 |      Notes
 |      -----
 |      See ``np.partition`` for notes on the different algorithms.
 |
 |      Examples
 |      --------
 |      >>> a = np.array([3, 4, 2, 1])
 |      >>> a.partition(3)
 |      >>> a
 |      array([2, 1, 3, 4])
 |
 |      >>> a.partition((1, 3))
 |      array([1, 2, 3, 4])
 |
 |  prod(...)
 |      a.prod(axis=None, dtype=None, out=None, keepdims=False)
 |
 |      Return the product of the array elements over the given axis
 |
 |      Refer to `numpy.prod` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.prod : equivalent function
 |
 |  ptp(...)
 |      a.ptp(axis=None, out=None, keepdims=False)
 |
 |      Peak to peak (maximum - minimum) value along a given axis.
 |
 |      Refer to `numpy.ptp` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.ptp : equivalent function
 |
 |  put(...)
 |      a.put(indices, values, mode='raise')
 |
 |      Set ``a.flat[n] = values[n]`` for all `n` in indices.
 |
 |      Refer to `numpy.put` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.put : equivalent function
 |
 |  ravel(...)
 |      a.ravel([order])
 |
 |      Return a flattened array.
 |
 |      Refer to `numpy.ravel` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.ravel : equivalent function
 |
 |      ndarray.flat : a flat iterator on the array.
 |
 |  repeat(...)
 |      a.repeat(repeats, axis=None)
 |
 |      Repeat elements of an array.
 |
 |      Refer to `numpy.repeat` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.repeat : equivalent function
 |
 |  reshape(...)
 |      a.reshape(shape, order='C')
 |
 |      Returns an array containing the same data with a new shape.
 |
 |      Refer to `numpy.reshape` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.reshape : equivalent function
 |
 |      Notes
 |      -----
 |      Unlike the free function `numpy.reshape`, this method on `ndarray` allows
 |      the elements of the shape parameter to be passed in as separate arguments.
 |      For example, ``a.reshape(10, 11)`` is equivalent to
 |      ``a.reshape((10, 11))``.
 |
 |  resize(...)
 |      a.resize(new_shape, refcheck=True)
 |
 |      Change shape and size of array in-place.
 |
 |      Parameters
 |      ----------
 |      new_shape : tuple of ints, or `n` ints
 |          Shape of resized array.
 |      refcheck : bool, optional
 |          If False, reference count will not be checked. Default is True.
 |
 |      Returns
 |      -------
 |      None
 |
 |      Raises
 |      ------
 |      ValueError
 |          If `a` does not own its own data or references or views to it exist,
 |          and the data memory must be changed.
 |          PyPy only: will always raise if the data memory must be changed, since
 |          there is no reliable way to determine if references or views to it
 |          exist.
 |
 |      SystemError
 |          If the `order` keyword argument is specified. This behaviour is a
 |          bug in NumPy.
 |
 |      See Also
 |      --------
 |      resize : Return a new array with the specified shape.
 |
 |      Notes
 |      -----
 |      This reallocates space for the data area if necessary.
 |
 |      Only contiguous arrays (data elements consecutive in memory) can be
 |      resized.
 |
 |      The purpose of the reference count check is to make sure you
 |      do not use this array as a buffer for another Python object and then
 |      reallocate the memory. However, reference counts can increase in
 |      other ways so if you are sure that you have not shared the memory
 |      for this array with another Python object, then you may safely set
 |      `refcheck` to False.
 |
 |      Examples
 |      --------
 |      Shrinking an array: array is flattened (in the order that the data are
 |      stored in memory), resized, and reshaped:
 |
 |      >>> a = np.array([[0, 1], [2, 3]], order='C')
 |      >>> a.resize((2, 1))
 |      >>> a
 |      array([[0],
 |             [1]])
 |
 |      >>> a = np.array([[0, 1], [2, 3]], order='F')
 |      >>> a.resize((2, 1))
 |      >>> a
 |      array([[0],
 |             [2]])
 |
 |      Enlarging an array: as above, but missing entries are filled with zeros:
 |
 |      >>> b = np.array([[0, 1], [2, 3]])
 |      >>> b.resize(2, 3) # new_shape parameter doesn't have to be a tuple
 |      >>> b
 |      array([[0, 1, 2],
 |             [3, 0, 0]])
 |
 |      Referencing an array prevents resizing...
 |
 |      >>> c = a
 |      >>> a.resize((1, 1))
 |      Traceback (most recent call last):
 |      ...
 |      ValueError: cannot resize an array that has been referenced ...
 |
 |      Unless `refcheck` is False:
 |
 |      >>> a.resize((1, 1), refcheck=False)
 |      >>> a
 |      array([[0]])
 |      >>> c
 |      array([[0]])
 |
 |  round(...)
 |      a.round(decimals=0, out=None)
 |
 |      Return `a` with each element rounded to the given number of decimals.
 |
 |      Refer to `numpy.around` for full documentation.
 |
 |      See Also
 |      --------
 |      numpy.around : equivalent function
 |
 |  searchsorted(...)
 |      a.searchsorted(v, side='left', sorter=None)
 |
 |      Find indices where elements of v should be inserted in a to maintain order.
 |
 |      For full documentation, see `numpy.searchsorted`
 |
 |      See Also
 |      --------
 |      numpy.searchsorted : equivalent function
 |
 |  setfield(...)

    """


def np_array():
    """
array(...)
    array(object, dtype=None, copy=True, order='K', subok=False, ndmin=0)

    Create an array.

    Parameters
    ----------
    object : array_like
        An array, any object exposing the array interface, an object whose
        __array__ method returns an array, or any (nested) sequence.
    dtype : data-type, optional
        The desired data-type for the array.  If not given, then the type will
        be determined as the minimum type required to hold the objects in the
        sequence.  This argument can only be used to 'upcast' the array.  For
        downcasting, use the .astype(t) method.
    copy : bool, optional
        If true (default), then the object is copied.  Otherwise, a copy will
        only be made if __array__ returns a copy, if obj is a nested sequence,
        or if a copy is needed to satisfy any of the other requirements
        (`dtype`, `order`, etc.).
    order : {'K', 'A', 'C', 'F'}, optional
        Specify the memory layout of the array. If object is not an array, the
        newly created array will be in C order (row major) unless 'F' is
        specified, in which case it will be in Fortran order (column major).
        If object is an array the following holds.

        ===== ========= ===================================================
        order  no copy                     copy=True
        ===== ========= ===================================================
        'K'   unchanged F & C order preserved, otherwise most similar order
        'A'   unchanged F order if input is F and not C, otherwise C order
        'C'   C order   C order
        'F'   F order   F order
        ===== ========= ===================================================

        When ``copy=False`` and a copy is made for other reasons, the result is
        the same as if ``copy=True``, with some exceptions for `A`, see the
        Notes section. The default order is 'K'.
    subok : bool, optional
        If True, then sub-classes will be passed-through, otherwise
        the returned array will be forced to be a base-class array (default).
    ndmin : int, optional
        Specifies the minimum number of dimensions that the resulting
        array should have.  Ones will be pre-pended to the shape as
        needed to meet this requirement.

    Returns
    -------
    out : ndarray
        An array object satisfying the specified requirements.

    See Also
    --------
    empty_like : Return an empty array with shape and type of input.
    ones_like : Return an array of ones with shape and type of input.
    zeros_like : Return an array of zeros with shape and type of input.
    full_like : Return a new array with shape of input filled with value.
    empty : Return a new uninitialized array.
    ones : Return a new array setting values to one.
    zeros : Return a new array setting values to zero.
    full : Return a new array of given shape filled with value.


    Notes
    -----
    When order is 'A' and `object` is an array in neither 'C' nor 'F' order,
    and a copy is forced by a change in dtype, then the order of the result is
    not necessarily 'C' as expected. This is likely a bug.

    Examples
    --------
    >>> np.array([1, 2, 3])
    array([1, 2, 3])

    Upcasting:

    >>> np.array([1, 2, 3.0])
    array([ 1.,  2.,  3.])

    More than one dimension:

    >>> np.array([[1, 2], [3, 4]])
    array([[1, 2],
           [3, 4]])

    Minimum dimensions 2:

    >>> np.array([1, 2, 3], ndmin=2)
    array([[1, 2, 3]])

    Type provided:

    >>> np.array([1, 2, 3], dtype=complex)
    array([ 1.+0.j,  2.+0.j,  3.+0.j])

    Data-type consisting of more than one element:

    >>> x = np.array([(1,2),(3,4)],dtype=[('a','<i4'),('b','<i4')])
    >>> x['a']
    array([1, 3])

    Creating an array from sub-classes:

    >>> np.array(np.mat('1 2; 3 4'))
    array([[1, 2],
           [3, 4]])

    >>> np.array(np.mat('1 2; 3 4'), subok=True)
    matrix([[1, 2],
            [3, 4]])


    :return:
    """


def np_zeros():
    """
    zeros(shape, dtype=float, order='C')

    Return a new array of given shape and type, filled with zeros.

    Parameters
    ----------
    shape : int or tuple of ints
        Shape of the new array, e.g., ``(2, 3)`` or ``2``.
    dtype : data-type, optional
        The desired data-type for the array, e.g., `numpy.int8`.  Default is
        `numpy.float64`.
    order : {'C', 'F'}, optional, default: 'C'
        Whether to store multi-dimensional data in row-major
        (C-style) or column-major (Fortran-style) order in
        memory.

    Returns
    -------
    out : ndarray
        Array of zeros with the given shape, dtype, and order.

    See Also
    --------
    zeros_like : Return an array of zeros with shape and type of input.
    empty : Return a new uninitialized array.
    ones : Return a new array setting values to one.
    full : Return a new array of given shape filled with value.

    Examples
    --------
    >>> np.zeros(5)
    array([ 0.,  0.,  0.,  0.,  0.])

    >>> np.zeros((5,), dtype=int)
    array([0, 0, 0, 0, 0])

    >>> np.zeros((2, 1))
    array([[ 0.],
           [ 0.]])

    >>> s = (2,2)
    >>> np.zeros(s)
    array([[ 0.,  0.],
           [ 0.,  0.]])

    >>> np.zeros((2,), dtype=[('x', 'i4'), ('y', 'i4')]) # custom dtype
    array([(0, 0), (0, 0)],
          dtype=[('x', '<i4'), ('y', '<i4')])

    :return:
    """


def np_savetxt_loadtxt():
    """
savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='', footer='', comments='# ', encoding=None)
    Save an array to a text file.

    Parameters
    ----------
    fname : filename or file handle
        If the filename ends in ``.gz``, the file is automatically saved in
        compressed gzip format.  `loadtxt` understands gzipped files
        transparently.
    X : 1D or 2D array_like
        Data to be saved to a text file.
    fmt : str or sequence of strs, optional
        A single format (%10.5f), a sequence of formats, or a
        multi-format string, e.g. 'Iteration %d -- %10.5f', in which
        case `delimiter` is ignored. For complex `X`, the legal options
        for `fmt` are:

        * a single specifier, `fmt='%.4e'`, resulting in numbers formatted
          like `' (%s+%sj)' % (fmt, fmt)`
        * a full string specifying every real and imaginary part, e.g.
          `' %.4e %+.4ej %.4e %+.4ej %.4e %+.4ej'` for 3 columns
        * a list of specifiers, one per column - in this case, the real
          and imaginary part must have separate specifiers,
          e.g. `['%.3e + %.3ej', '(%.15e%+.15ej)']` for 2 columns
    delimiter : str, optional
        String or character separating columns.
    newline : str, optional
        String or character separating lines.

        .. versionadded:: 1.5.0
    header : str, optional
        String that will be written at the beginning of the file.

        .. versionadded:: 1.7.0
    footer : str, optional
        String that will be written at the end of the file.

        .. versionadded:: 1.7.0
    comments : str, optional
        String that will be prepended to the ``header`` and ``footer`` strings,
        to mark them as comments. Default: '# ',  as expected by e.g.
        ``numpy.loadtxt``.

        .. versionadded:: 1.7.0
    encoding : {None, str}, optional
        Encoding used to encode the outputfile. Does not apply to output
        streams. If the encoding is something other than 'bytes' or 'latin1'
        you will not be able to load the file in NumPy versions < 1.14. Default
        is 'latin1'.

        .. versionadded:: 1.14.0


    See Also
    --------
    save : Save an array to a binary file in NumPy ``.npy`` format
    savez : Save several arrays into an uncompressed ``.npz`` archive
    savez_compressed : Save several arrays into a compressed ``.npz`` archive

    Notes
    -----
    Further explanation of the `fmt` parameter
    (``%[flag]width[.precision]specifier``):

    flags:
        ``-`` : left justify

        ``+`` : Forces to precede result with + or -.

        ``0`` : Left pad the number with zeros instead of space (see width).
    width:
        Minimum number of characters to be printed. The value is not truncated
        if it has more characters.

    precision:
        - For integer specifiers (eg. ``d,i,o,x``), the minimum number of
          digits.
        - For ``e, E`` and ``f`` specifiers, the number of digits to print
          after the decimal point.
        - For ``g`` and ``G``, the maximum number of significant digits.
        - For ``s``, the maximum number of characters.

    specifiers:
        ``c`` : character

        ``d`` or ``i`` : signed decimal integer
        ``e`` or ``E`` : scientific notation with ``e`` or ``E``.

        ``f`` : decimal floating point

        ``g,G`` : use the shorter of ``e,E`` or ``f``

        ``o`` : signed octal

        ``s`` : string of characters

        ``u`` : unsigned decimal integer

        ``x,X`` : unsigned hexadecimal integer

    This explanation of ``fmt`` is not complete, for an exhaustive
    specification see [1]_.

    This explanation of ``fmt`` is not complete, for an exhaustive
    specification see [1]_.

    References
    ----------
    .. [1] `Format Specification Mini-Language
           <https://docs.python.org/library/string.html#format-specification-mini-language>`_,
           Python Documentation.

    Examples
    --------
    >>> x = y = z = np.arange(0.0,5.0,1.0)
    >>> np.savetxt('syntax.out', x, delimiter=',')   # X is an array
    >>> np.savetxt('syntax.out', (x,y,z))   # x,y,z equal sized 1D arrays
    >>> np.savetxt('syntax.out', x, fmt='%1.4e')   # use exponential notation
    """

    # loadtxt
    """
loadtxt(fname, dtype=<class 'float'>, comments='#', delimiter=None, converters=None, skiprows=0, usecols=None,
        unpack=False, ndmin=0, encoding='bytes', max_rows=None)

    Load data from a text file.

    Each row in the text file must have the same number of values.

    Parameters
    ----------
    fname : file, str, or pathlib.Path
        File, filename, or generator to read.  If the filename extension is
        ``.gz`` or ``.bz2``, the file is first decompressed. Note that
        generators should return byte strings for Python 3k.
    dtype : data-type, optional
        Data-type of the resulting array; default: float.  If this is a
        structured data-type, the resulting array will be 1-dimensional, and
        each row will be interpreted as an element of the array.  In this
        case, the number of columns used must match the number of fields in
        the data-type.
    comments : str or sequence of str, optional
        The characters or list of characters used to indicate the start of a
        comment. None implies no comments. For backwards compatibility, byte
        strings will be decoded as 'latin1'. The default is '#'.
    delimiter : str, optional
        The string used to separate values. For backwards compatibility, byte
        strings will be decoded as 'latin1'. The default is whitespace.
    converters : dict, optional
        A dictionary mapping column number to a function that will parse the
        column string into the desired value.  E.g., if column 0 is a date
        string: ``converters = {0: datestr2num}``.  Converters can also be
        used to provide a default value for missing data (but see also
        `genfromtxt`): ``converters = {3: lambda s: float(s.strip() or 0)}``.
        Default: None.
    skiprows : int, optional
        Skip the first `skiprows` lines, including comments; default: 0.
    usecols : int or sequence, optional
        Which columns to read, with 0 being the first. For example,
        ``usecols = (1,4,5)`` will extract the 2nd, 5th and 6th columns.
        The default, None, results in all columns being read.

        .. versionchanged:: 1.11.0
            When a single column has to be read it is possible to use
            an integer instead of a tuple. E.g ``usecols = 3`` reads the
            fourth column the same way as ``usecols = (3,)`` would.
    unpack : bool, optional
        If True, the returned array is transposed, so that arguments may be
        unpacked using ``x, y, z = loadtxt(...)``.  When used with a structured
        data-type, arrays are returned for each field.  Default is False.
    ndmin : int, optional
        The returned array will have at least `ndmin` dimensions.
        Otherwise mono-dimensional axes will be squeezed.
        Legal values: 0 (default), 1 or 2.

        .. versionadded:: 1.6.0
    encoding : str, optional
        Encoding used to decode the inputfile. Does not apply to input streams.
        The special value 'bytes' enables backward compatibility workarounds
        that ensures you receive byte arrays as results if possible and passes
        'latin1' encoded strings to converters. Override this value to receive
        unicode arrays and pass strings as input to converters.  If set to None
        the system default is used. The default value is 'bytes'.

        .. versionadded:: 1.14.0
    max_rows : int, optional
        Read `max_rows` lines of content after `skiprows` lines. The default
        is to read all the lines.

        .. versionadded:: 1.16.0

    Returns
    -------
    out : ndarray
        Data read from the text file.

    See Also
    --------
    load, fromstring, fromregex
    genfromtxt : Load data with missing values handled as specified.
    scipy.io.loadmat : reads MATLAB data files

    :param file:
    :return:
    """

    data1 = np.empty((3, 3), dtype=np.float16)
    np.savetxt('demo_np_savetxt.txt', data1, fmt='%.6f', delimiter=',')
    data2 = np.loadtxt('demo_np_savetxt.txt', dtype=np.float, delimiter=',')
    print(
        "#使用empty方法生成多维数组 \n"
        " >>> data1 = np.empty((3, 3), dtype=np.float16)\n"
        " >>> data1\n"
        f"{data1,}\n"
        "# 使用np.savetxt保存数据到文本文件\n"
        " >>> np.savetxt('demo_np_savetxt.txt', data1, fmt='%.6f', delimiter=',')\n"
        "# 通过open方法读出打印文件内容\n"
        " >>> with open('demo_np_savetxt.txt') as fp:\n"
        " ...     for line in fp.readlines():\n"
        " ...         print(line)\n"
    )
    with open('demo_np_savetxt.txt') as fp:
        for line in fp.readlines():
            print(line, end='')
    print(
        "# 使用np.loadtxt读出文件到numpy数组\n"
        " >>> data2 = np.loadtxt('demo_np_savetxt.txt', dtype=np.float, delimiter=',')\n"
        " >>> data2\n"
        f"{data2, data2.dtype}\n"
    )
    # return
    # data = np.loadtxt(file, delimiter=',', dtype=np.uint)
    return


def np_save_load():
    """
save(file, arr, allow_pickle=True, fix_imports=True)
    Save an array to a binary file in NumPy ``.npy`` format.

    Parameters
    ----------
    file : file, str, or pathlib.Path
        File or filename to which the data is saved.  If file is a file-object,
        then the filename is unchanged.  If file is a string or Path, a ``.npy``
        extension will be appended to the file name if it does not already
        have one.
    arr : array_like
        Array data to be saved.
    allow_pickle : bool, optional
        Allow saving object arrays using Python pickles. Reasons for disallowing
        pickles include security (loading pickled data can execute arbitrary
        code) and portability (pickled objects may not be loadable on different
        Python installations, for example if the stored objects require libraries
        that are not available, and not all pickled data is compatible between
        Python 2 and Python 3).
        Default: True
    fix_imports : bool, optional
        Only useful in forcing objects in object arrays on Python 3 to be
        pickled in a Python 2 compatible way. If `fix_imports` is True, pickle
        will try to map the new Python 3 names to the old module names used in
        Python 2, so that the pickle data stream is readable with Python 2.

    See Also
    --------
    savez : Save several arrays into a ``.npz`` archive
    savetxt, load

    Notes
    -----
    For a description of the ``.npy`` format, see :py:mod:`numpy.lib.format`.

    Examples
    --------
    >>> from tempfile import TemporaryFile
    >>> outfile = TemporaryFile()

    >>> x = np.arange(10)
    >>> np.save(outfile, x)

    >>> _ = outfile.seek(0) # Only needed here to simulate closing & reopening file
    >>> np.load(outfile)
    array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    """

    # load
    """
load(file, mmap_mode=None, allow_pickle=False, fix_imports=True, encoding='ASCII')
    Load arrays or pickled objects from ``.npy``, ``.npz`` or pickled files.

    .. warning:: Loading files that contain object arrays uses the ``pickle``
                 module, which is not secure against erroneous or maliciously
                 constructed data. Consider passing ``allow_pickle=False`` to
                 load data that is known not to contain object arrays for the
                 safer handling of untrusted sources.

    Parameters
    ----------
    file : file-like object, string, or pathlib.Path
        The file to read. File-like objects must support the
        ``seek()`` and ``read()`` methods. Pickled files require that the
        file-like object support the ``readline()`` method as well.
    mmap_mode : {None, 'r+', 'r', 'w+', 'c'}, optional
        If not None, then memory-map the file, using the given mode (see
        `numpy.memmap` for a detailed description of the modes).  A
        memory-mapped array is kept on disk. However, it can be accessed
        and sliced like any ndarray.  Memory mapping is especially useful
        for accessing small fragments of large files without reading the
        entire file into memory.
    allow_pickle : bool, optional
        Allow loading pickled object arrays stored in npy files. Reasons for
        disallowing pickles include security, as loading pickled data can
        execute arbitrary code. If pickles are disallowed, loading object
        arrays will fail. Default: False

        .. versionchanged:: 1.16.3
            Made default False in response to CVE-2019-6446.

    fix_imports : bool, optional
        Only useful when loading Python 2 generated pickled files on Python 3,
        which includes npy/npz files containing object arrays. If `fix_imports`
        is True, pickle will try to map the old Python 2 names to the new names
        used in Python 3.
    encoding : str, optional
        What encoding to use when reading Python 2 strings. Only useful when
        loading Python 2 generated pickled files in Python 3, which includes
        npy/npz files containing object arrays. Values other than 'latin1',
        'ASCII', and 'bytes' are not allowed, as they can corrupt numerical
        data. Default: 'ASCII'

    Returns
    -------
    result : array, tuple, dict, etc.
        Data stored in the file. For ``.npz`` files, the returned instance
        of NpzFile class must be closed to avoid leaking file descriptors.

    Raises
    ------
    IOError
        If the input file does not exist or cannot be read.
    ValueError
        The file contains an object array, but allow_pickle=False given.

    See Also
    --------
    save, savez, savez_compressed, loadtxt
    memmap : Create a memory-map to an array stored in a file on disk.
    lib.format.open_memmap : Create or load a memory-mapped ``.npy`` file.

    Notes
    -----
    - If the file contains pickle data, then whatever object is stored
      in the pickle is returned.
    - If the file is a ``.npy`` file, then a single array is returned.
    - If the file is a ``.npz`` file, then a dictionary-like object is
      returned, containing ``{filename: array}`` key-value pairs, one for
      each file in the archive.
    - If the file is a ``.npz`` file, the returned value supports the
      context manager protocol in a similar fashion to the open function::

        with load('foo.npz') as data:
            a = data['a']

      The underlying file descriptor is closed when exiting the 'with'
      block.

    Examples
    --------
    Store data to disk, and load it again:

    >>> np.save('/tmp/123', np.array([[1, 2, 3], [4, 5, 6]]))
    >>> np.load('/tmp/123.npy')
    array([[1, 2, 3],
           [4, 5, 6]])

    Store compressed data to disk, and load it again:

    >>> a=np.array([[1, 2, 3], [4, 5, 6]])
    >>> b=np.array([1, 2])
    >>> np.savez('/tmp/123.npz', a=a, b=b)
    >>> data = np.load('/tmp/123.npz')
    >>> data['a']
    array([[1, 2, 3],
           [4, 5, 6]])
    >>> data['b']
    array([1, 2])
    >>> data.close()

    Mem-map the stored array, and then access the second row
    directly from disk:

    >>> X = np.load('/tmp/123.npy', mmap_mode='r')
    >>> X[1, :]
    memmap([4, 5, 6])
    """

    a = np.random.random((3, 3))
    np.save('demo_numpy_save.npy', a)
    np.save('demo_numpy_save2', a)
    b = np.load('demo_numpy_save.npy')
    c = np.load('demo_numpy_save2.npy')
    print(
        " >>> a = np.random.random((3, 3))\n"
        "# 使用扩展名保存数组为二进制数据文件\n"
        " >>> np.save('demo_numpy_save.npy', a)\n"
        " >>> b = np.load('demo_numpy_save.npy')\n"
        " >>> b\n"
        f"{b, b.dtype}\n"
        f"# 未添加扩展名.npy\n"
        " >>> np.save('demo_numpy_save2', a)\n"
        " >>> c = np.load('demo_numpy_save2.npy')\n"
        " >>> c\n"
        f"{c, c.dtype}"
    )
    return


def np_save_vs_savetxt():
    import time
    a = np.random.random((10000, 300))
    start = time.time(); np.savetxt('demo.txt', a);t1 = time.time() - start
    start = time.time(); np.save('demo.npy', a); t2 = time.time() - start
    start = time.time(); np.loadtxt('demo.txt'); t3 = time.time() - start
    start = time.time(); np.load('demo.npy'); t4 = time.time() - start
    print(
        "# 比较np.save与np.savetxt的效率\n"
        " >>> a = np.random.random((10000, 300))\n"
        " >>> start=time.time();np.savetxt('demo.txt', a);print(time.time()-start)\n"
        f"{t1}\n"
        " >>> start=time.time();np.save('demo.npy', a);print(time.time()-start)\n"
        f"{t2}    # 写入速度为loadtxt的{'{:.1f}'.format(t1/t2)}倍\n"
        " >>> start=time.time();np.loadtxt('demo.txt', a);print(time.time()-start)\n"
        f"{t3}\n"
        " >>> start=time.time();np.load('demo.npy', a);print(time.time()-start)\n"
        f"{t4}    # 读取速度为loadtxt的{'{:.1f}'.format(t3/t4)}倍\n"
    )
    return


def np_userdtype_save_load():
    """
    save student score data
    :param file: str, save or load data to text file
    """
    data = [
        ('Zhai Linwei', [80, 87, 92], 259),
        ('Zhou Geshan', [90, 80, 88], 258),
        ('Zang Keting', [67, 73, 70], 210),
    ]

    # mode-1
    np_data = np.array(data, dtype='U20, 3u1, u2')
    np.savetxt('temp_ndarray1.txt', np_data, fmt='%-15s', delimiter=',', encoding='utf8')
    np_load_data = np.loadtxt('temp_ndarray1.txt', dtype='U15, U15, U15', delimiter=',', encoding='utf8')
    print('ndarray: dtype={(U20, 3u1, u2)}, save to: temp_ndarray1.txt\n'
          f"{np_data}\n"
          f" >>> np.savetxt('temp_ndarray1.txt', np_data, fmt='%-15s', delimiter=',', encoding='utf8')\n"
          f" >>> np_load_data = np.loadtxt(file, dtype='U15, U15, U15', delimiter=',', encoding='utf8')\n"
          f"ndarray read from text file:\n"
          f"{np_load_data}\n"
          )
    # print('ndarray read from text file:')
    # print(np_load_data, '\n')

    # mode-2
    score_type = np.dtype([('name', 'U20'), ('majors', '3u1'), ('total', 'u2')])
    np_data2 = np.array(data, dtype=score_type)
    np.savetxt('temp_ndarray2.txt', np_data2, fmt='%s,%s,%d', delimiter=',', encoding='utf8')
    print('ndarray: new dtype={(U20), (3u1), (u2)}\n'
          " >>> score_type = np.dtype([('name', 'U20'), ('majors', '3u1'), ('total', 'u2')])\n"
          " >>> np_data2 = np.array(data, dtype=score_type)\n"
          " >>> np_data2\n"
          f"{np_data2}\n"
          " >>> np.savetxt('temp_ndarray2.txt', np_data2, fmt='%-10s,%10s,%d', delimiter=',', encoding='utf8')\n"
          " >>> with open('temp_ndarray2.txt', 'rt') as fp:\n"
          " ...     for line in fp.readlines():\n"
          " ...         print(line)\n"
          # f"{np.loadtxt('temp_ndarray2.txt')}"
          )
    with open('temp_ndarray2.txt', 'rt') as fp:
        for line in fp.readlines():
            print(line)


def np_record_dtype():
    """
    numpy dtype for record
    :param file: str, save or load data to nparray
    """

    # dtype for record
    score_type = np.dtype(
        [('name', 'U20'),
         ('science', 'u1'),
         ('math', 'u1'),
         ('physics', 'u1'),
         ('total', 'u2')
         ])
    # source data
    students = [
        ('Zhai Linwei', 80, 87, 92, 259),
        ('Zhou Geshan', 90, 80, 88, 258),
        ('Zang Keting', 67, 73, 70, 210),
    ]
    # numpy record data
    np_students = np.array(students, dtype=score_type)

    # calculate using numpy record data
    print('max(science)={}, mean(math)={}, std(total)={:.2f}'.format(
        np_students['science'].max(),
        np_students['math'].mean(),
        np_students['total'].std()))

    # save numpy record data to text file
    np.savetxt('demo_numpy_record.txt')
    return
